﻿using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Input;
using System;

namespace Bunbyx.game
{
    public class ScoreScreen : Screen
    {
        // --------------------------------------------------------------------
        //  Delegates
        // --------------------------------------------------------------------

        public delegate void NextLevel();

        // --------------------------------------------------------------------
        //  Constants
        // --------------------------------------------------------------------

        private const string SCREEN_NAME = "Screens/pause";

        public const int CARROT_MULTIPLIER = 150;
        public const int SALAD_MULTIPLIER = 200;
        public const int GOLD_IDOL_MULTIPLIER = 500;
        public const int SECOND_MULTIPLIER = 42;

        private const int PROGRESSIVE_SCORE_DURATION = 1000;
        private const int SCREEN_MIN_DURATION = 3000;

        private Vector2 CARROT_SCORE_POSITION = new Vector2(180, 20);
        private Vector2 SALAD_SCORE_POSITION = new Vector2(180, 100);
        private Vector2 GOLD_IDOL_SCORE_POSITION = new Vector2(180, 180);
        private Vector2 TIME_SCORE_POSITION = new Vector2(180, 260);
        private Vector2 FINAL_SCORE_POSITION = new Vector2(180, 380);

        private Vector2 ITEM_COUNT_POSITION_OFFSET = new Vector2(80, 0);
        private Vector2 ITEM_MULTIPLIER_POSITION_OFFSET = new Vector2(150, 0);
        private Vector2 ITEM_TOTAL_POSITION_OFFSET = new Vector2(300, 0);

        private Vector2 NEW_RECORD_POSITION = new Vector2(320, 320);

        // --------------------------------------------------------------------
        //  Attributes
        // --------------------------------------------------------------------

        private Camera camera;
        private Hud hud;
        private SpriteFont font;

        private int timeCounter;
        private float percentDisplay;
        private long finalScore;
        private long remainingTime;
        private bool isBestScore;

        private Sprite carrotSprite;
        private Sprite saladSprite;
        private Sprite idolGoldSprite;
        private Sprite clockSprite;

        private NextLevel nextLevelHandler;

        // --------------------------------------------------------------------
        //  Constructor
        // --------------------------------------------------------------------

        public ScoreScreen(Camera camera, Hud hud, NextLevel nextLevelHandler)
        {
            this.camera = camera;
            this.hud = hud;
            this.nextLevelHandler = nextLevelHandler;
            this.remainingTime = hud.MaxTime / 1000;
            this.timeCounter = 0;
            this.percentDisplay = 0;
            this.isBestScore = false;

            this.carrotSprite = new Sprite(Sprite.SpriteType.Carrot, camera.Position + CARROT_SCORE_POSITION);
            this.saladSprite = new Sprite(Sprite.SpriteType.Salad, camera.Position + SALAD_SCORE_POSITION);
            this.idolGoldSprite = new Sprite(Sprite.SpriteType.IdolGold, camera.Position + GOLD_IDOL_SCORE_POSITION);
            this.clockSprite = new Sprite(Sprite.SpriteType.Clock, camera.Position + TIME_SCORE_POSITION);

            finalScore =
                hud.CarrotCount * CARROT_MULTIPLIER +
                hud.SaladCount * SALAD_MULTIPLIER +
                hud.IdolGoldCount * GOLD_IDOL_MULTIPLIER +
                remainingTime * SECOND_MULTIPLIER;
        }

        // --------------------------------------------------------------------
        //  Public methods
        // --------------------------------------------------------------------

        public override void LoadContent(ContentManager content)
        {
            font = content.Load<SpriteFont>(Hud.BIG_FONT_NAME);

            carrotSprite.LoadContent(content);
            saladSprite.LoadContent(content);
            idolGoldSprite.LoadContent(content);
            clockSprite.LoadContent(content);
        }

        public override void Update(GameTime gameTime)
        {
            timeCounter += gameTime.ElapsedGameTime.Milliseconds;
            percentDisplay = Math.Min((float)timeCounter / PROGRESSIVE_SCORE_DURATION, 1);

            if (timeCounter >= SCREEN_MIN_DURATION && Keyboard.GetState().GetPressedKeys().Length > 0)
            {
                nextLevelHandler();
            }
        }

        public override void Draw(SpriteBatch spriteBatch)
        {
            // Draw icons
            carrotSprite.Draw(spriteBatch);
            saladSprite.Draw(spriteBatch);
            idolGoldSprite.Draw(spriteBatch);
            clockSprite.Draw(spriteBatch);

            // Draw counters
            spriteBatch.DrawString(font, progressiveRound(hud.CarrotCount), camera.Position + CARROT_SCORE_POSITION + ITEM_COUNT_POSITION_OFFSET, Color.Black);
            spriteBatch.DrawString(font, progressiveRound(hud.SaladCount), camera.Position + SALAD_SCORE_POSITION + ITEM_COUNT_POSITION_OFFSET, Color.Black);
            spriteBatch.DrawString(font, progressiveRound(hud.IdolGoldCount), camera.Position + GOLD_IDOL_SCORE_POSITION + ITEM_COUNT_POSITION_OFFSET, Color.Black);
            spriteBatch.DrawString(font, progressiveRound(remainingTime), camera.Position + TIME_SCORE_POSITION + ITEM_COUNT_POSITION_OFFSET, Color.Black);

            // Draw multipliers
            spriteBatch.DrawString(font, "x " + progressiveRound(CARROT_MULTIPLIER), camera.Position + CARROT_SCORE_POSITION + ITEM_MULTIPLIER_POSITION_OFFSET, Color.Black);
            spriteBatch.DrawString(font, "x " + progressiveRound(SALAD_MULTIPLIER), camera.Position + SALAD_SCORE_POSITION + ITEM_MULTIPLIER_POSITION_OFFSET, Color.Black);
            spriteBatch.DrawString(font, "x " + progressiveRound(GOLD_IDOL_MULTIPLIER), camera.Position + GOLD_IDOL_SCORE_POSITION + ITEM_MULTIPLIER_POSITION_OFFSET, Color.Black);
            spriteBatch.DrawString(font, "x " + progressiveRound(SECOND_MULTIPLIER), camera.Position + TIME_SCORE_POSITION + ITEM_MULTIPLIER_POSITION_OFFSET, Color.Black);

            // Draw totals
            spriteBatch.DrawString(font, "= " + progressiveRound(hud.CarrotCount * CARROT_MULTIPLIER), camera.Position + CARROT_SCORE_POSITION + ITEM_TOTAL_POSITION_OFFSET, Color.Black);
            spriteBatch.DrawString(font, "= " + progressiveRound(hud.SaladCount * SALAD_MULTIPLIER), camera.Position + SALAD_SCORE_POSITION + ITEM_TOTAL_POSITION_OFFSET, Color.Black);
            spriteBatch.DrawString(font, "= " + progressiveRound(hud.IdolGoldCount * GOLD_IDOL_MULTIPLIER), camera.Position + GOLD_IDOL_SCORE_POSITION + ITEM_TOTAL_POSITION_OFFSET, Color.Black);
            spriteBatch.DrawString(font, "= " + progressiveRound(remainingTime * SECOND_MULTIPLIER), camera.Position + TIME_SCORE_POSITION + ITEM_TOTAL_POSITION_OFFSET, Color.Black);

            // Final score
            spriteBatch.DrawString(font, "= " + progressiveRound(finalScore), camera.Position + FINAL_SCORE_POSITION + ITEM_TOTAL_POSITION_OFFSET, Color.Black);

            if (percentDisplay == 1 && isBestScore)
            {
                spriteBatch.DrawString(font, "New record!", camera.Position + NEW_RECORD_POSITION, Color.Gold);
            }
        }

        public long GetTotalScore()
        {
            return finalScore;
        }

        public void IsBestScore()
        {
            isBestScore = true;
        }

        // --------------------------------------------------------------------
        //  Private methods
        // --------------------------------------------------------------------

        private String progressiveRound(long value)
        {
            return ((int)Math.Round(value * percentDisplay)).ToString();
        }
    }
}
